<template>
  <div class="customFrom">
    <el-form
      style="width: 100%"
      :model="formData"
      :label-width="labelWidth"
      label-position="left"
      ref="ruleFormRef"
      :rules="fromRules"
      status-icon
    >
      <el-form-item
        v-for="(item, index) in fieldList"
        :label="item.label"
        key="index"
        :prop="item.name"
        style="width: 100%"
      >
        <el-select
          style="width: 80%"
          v-model="formData[item.name]"
          v-if="item.type == 'SELECT'"
          placeholder="请选择值"
        >
          <el-option
            v-for="(selectItem, index) in item.selectValue"
            :key="index"
            :label="selectItem.label"
            :value="selectItem.value"
          />
        </el-select>

        <el-select
          allow-create
          filterable
          style="width: 80%"
          v-model="formData[item.name]"
          v-if="item.type == 'SELECT_WRITE'"
          placeholder="请选择或输入值"
        >
          <el-option
            v-for="(selectItem, index) in item.selectValue"
            :key="index"
            :label="selectItem.label"
            :value="selectItem.value"
          />
        </el-select>

        <!-- 数字 -->
        <el-input-number
          v-model="formData[item.name]"
          v-if="item.type == 'NUMBER'"
          controls-position="right"
        />

        <!-- 文件 -->
        <div>
          <FileButton
            v-if="item.type == 'FILE'"
            v-model:data-list="formData[item.name]"
          ></FileButton>
        </div>

        <!-- <el-input-number v-model="formData[item.name]" v-if="item.type == 'FILE'" controls-position="right" /> -->

        <!-- 日期时间 -->
        <el-date-picker
          v-if="item.type == 'DATETIME'"
          v-model="formData[item.name]"
          type="datetime"
          placeholder="选择日期和时间"
        />

        <!-- 长文本 -->
        <el-input
          v-model="formData[item.name]"
          v-else-if="item.type == 'LONGTEXT'"
          :rows="3"
          type="textarea"
          style="width: 80%"
          placeholder="请输入"
       
        ></el-input>

        <!-- 图片 -->
        <el-upload
          class="image-upload"
          v-model:file-list="tempImageFiles[item.name]"
          :auto-upload="false"
          action="#"
          list-type="picture-card"
          v-else-if="item.type == 'IMAGE'"
          :limit="9"
        >
          <el-icon>
            <Plus />
          </el-icon>
        </el-upload>

        <!-- 单个照片（头像） -->
        <el-upload
          class="single-image-upload"
          :show-file-list="false"
          :auto-upload="false"
          action="#"
          :limit="2"
          list-type="picture-card"
          :on-change="(uploadFile: UploadFile, uploadFiles: UploadFiles) => { handleChange(uploadFile, uploadFiles, item.name) }"
          v-else-if="item.type == 'SINGLEIMAGE'"
        >
          <img
            class="single-image"
            v-if="singleImage[item.name]"
            :src="singleImage[item.name]"
            fit="cover"
          />
          <el-icon v-else class="single-image-icon">
            <Plus />
          </el-icon>
        </el-upload>

        <!-- 文本 -->
        <el-input
          style="width: 80%"
          v-model="formData[item.name]"
          v-else-if="item.type == 'TEXT'"
          :maxlength="item.maxlength?item.maxlength:'60'" show-word-limit
        >
        </el-input>

        <!-- 只读文本 -->
        <el-input
          disabled
          style="width: 80%"
          v-model="formData[item.name]"
          v-else-if="item.type == 'TEXT-DISABLED'"
        >
        </el-input>

        <!-- 插槽 -->
        <slot :name="item.name" v-if="item.type == 'SLOT'"> </slot>
      </el-form-item>
    </el-form>
    <div>
      <el-button @click="close">取 消</el-button>
      <el-button type="primary" @click="uploadImages(ruleFormRef)" :loading="isLoading"
        >确 定</el-button
      >
    </div>
  </div>
</template>

<script lang="ts" setup>
import {
  reactive,
  onMounted,
  getCurrentInstance,
  ComponentInternalInstance,
  ref,
  inject,
} from "vue";
import { Plus } from "@element-plus/icons-vue";
import {
  UploadUserFile,
  UploadStatus,
  UploadFile,
  UploadFiles,
  UploadRawFile,
  ElMessage,
} from "element-plus";
import metafile from "@/network/api/ossFile";
import FileButton from "../button/FileButton.vue";
import type { FormInstance, FormRules } from "element-plus";
import _, { indexOf } from "lodash";
import request from "@/network/request";
import { tr } from "element-plus/es/locale";
/**
 * 
 * 版本号：V1.1.0
 * 日期：2023年1月9日
 * 作者：陆银超
 * 邮箱：luyinchao@utum.cn
 * 预计更新：SELECT url功能配合字典使用
 *          SELECT 中添加label和value属性
 * 
 * 
 * fromDta: 表单对象数据
 * 
 * fieldList:
 *      {
             name: "field1",
            label: "标签1",
            type:"NUMBER",
            selectValue:[] //若数据类型为SELECT   需要添加selectValue数组值
        }    对象数组

     name： 对象中字段名 
     label：表单中抬头名称
 *   type: 'NUMBER'|'LONGTEXT'|'SINGLEIMAGE'|'TEXT'|'IMAGE'|'LONGTEXT'|'SLOT'|SELECT/数据类型
 *
 *rules:
 *  表单校验规则：参看element表单校验规则
 * 
 * labelWidth:左侧文字宽度
 * 
 * 
 */
/** emit
 *
 * submit:
 *   提交表单数据
 *
 */
const isLoading=ref(false)
//定义v-model:file-list 可以识别的对象接口
interface ImageFiles {
  [propName: string]: UploadUserFile[];
}

const { emit } = getCurrentInstance() as ComponentInternalInstance;
const props = defineProps({
  formData: {
    type: Object,
    default: () => ({}),
  },
  fieldList: {
    type: Object,
    default: () => [{}],
  },
  fromRules: {
    type: Object,
    default: () => ({}),
  },
  labelWidth: {
    type: String,
    default: "100px",
  },
  autoUpload: {
    type: Boolean,
    default: false,
  },
  imageWidth: {
    type: String,
    default: "64px",
  },
  longcode: {
    type: String,
    default: "",
  },
  afterSuccess:{
    type: String,
    default: "loading",
  }
  // refName:{
  //   type: String,
  //   default: "customFrom"
  // },
});

const baseUrl = inject("imageApi");
const UploadReadyStatus: UploadStatus = "ready";

//定义map对象 负责存储临时图片文件
//UploadUserFile 只有name是必填的
const tempImageFiles: ImageFiles = reactive({});

//
const singleImage: any = reactive({});

onMounted(() => {
  console.log(`the component is now mounted.`);
  //初始时 如果有图片 进行图片转化操作  将 原图片转化为 element ui 能读取的图片
  imageData2tempImageFiles(props.formData, props.fieldList);
  // formData.code=props.longcode
  //将远端url的值提取出，构成options
  selectUrl2SelectOptions(props.fieldList);
});

/**
 * 2023年1月11日新增
 * 将远端url的值提取出，构成options 填充进field 的selectValue
 *
 */
const selectUrl2SelectOptions = async (fields: Object) => {
  let tempFields: any = fields;
  console.log("子组件方法");

  for (let i = 0; i < tempFields.length; i++) {
    let field: any = tempFields[i];
    if (
      (field.type == "SELECT" || field.type == "SELECT_WRITE") &&
      !_.isEmpty(field.selectUrl)
    ) {
      let res = await request.post(field.selectUrl, field.selectParam);
      field.selectValue = res.singleData;
    }
  }
};

/**
 * 将原始数据转化为 ImageFiles 和singleImage
 * @param data 自定义数据值
 * @param fields 字段列表
 */
const imageData2tempImageFiles = (data: Object, fields: Object) => {
  let tempFields: any = fields;
  let tempData: any = data;

  for (let i = 0; i < tempFields.length; i++) {
    let field: any = tempFields[i];
    if (field.type == "IMAGE") {
      //获取原始数据
      if (tempData[field.name] == null || tempData[field.name].length < 5) {
        continue;
      }
      let images = JSON.parse(tempData[field.name]);
      //构建临时对象数组
      let tempUploadUserFiles: UploadUserFile[] = [];
      //取出原始数据 构建UploadUserFile[]
      console.log(images);
      for (let j = 0; j < images.length; j++) {
        let image = images[j];
        //name值为数据库文件名,未更改情况下可以赋值回data继续使用
        let tempUploadUserFile: UploadUserFile = {
          name: image,
          url: (baseUrl as any).value + image,
        };
        tempUploadUserFiles.push(tempUploadUserFile);
      }
      tempImageFiles[field.name] = tempUploadUserFiles;
    } else if (field.type == "SINGLEIMAGE") {
      if (tempData[field.name] == null || tempData[field.name].length < 5) {
        continue;
      }
      let images = JSON.parse(tempData[field.name]);
      singleImage[field.name] = (baseUrl as any) + images[0];
    }
  }
};

/**
 * 将ImageFiles转化为能够存储到数据库的格式
 * @param data
 * @param fields
 */
const tempImageFiles2Data = async (data: Object, fields: Object) => {
  let tempFields: any = fields;
  let tempData: any = data;

  for (let i = 0; i < tempFields.length; i++) {
    let field: any = tempFields[i];
    if (field.type == "IMAGE" || field.type == "SINGLEIMAGE") {
      let tempResultImages: any = [];
      let uploadFiles: UploadUserFile[] = tempImageFiles[field.name];

      //值为空的时候直接退出
      if (uploadFiles == undefined) {
        return;
      }

      for (let j = 0; j < uploadFiles.length; j++) {
        let res = (await uploadFile(uploadFiles[j])) as any;
        console.log(res);

        if (undefined != res.filename) {
          console.log(res.filename);
          tempResultImages.push(res.filename);
        }

        tempData[field.name] = JSON.stringify(tempResultImages);
      }
    }
  }
};
watch(()=>props.afterSuccess,(newValue, oldValue)=>{
  if (newValue='success') {
    isLoading.value=false
  }
})
/**
 * 单个文件上传 返回文件名
 * @param file
 */
const uploadFile = async (file: UploadUserFile): Promise<any> => {
  const imageName = { filename: file.name };
};

props.formData;
props.fieldList;

const ruleFormRef = ref<FormInstance>();

/**
 * @wwh
 * 提交表单时候 如果有多于这种字符限制提示多于，如果不是就是没选
 * @param formEl
 */
const uploadImages = async (formEl: FormInstance | undefined) => {
  if (!formEl) return;
  console.log(formEl.validate);
  isLoading.value=true
  await formEl.validate(async (valid, fields) => {
    console.log(fields);
    console.log(valid);
    var problem = false;
    if (fields === undefined) {
      await tempImageFiles2Data(props.formData, props.fieldList);
      emit("submit");
    } else {
      for (let key in fields as any) {
        const str = (fields as any)[key][0].message;
        if (str.indexOf("多于") > -1) {
          console.log("多了");
          ElMessage.info((fields as any)[key][0].message);
          delete (fields as any)[key];
          problem = true;
        } else {
          if (!problem) {
            console.log('有必填项未填！');
            
            ElMessage.info("有必填项未填！");
     
            problem = true;
          }
        }
      }
    }
    isLoading.value=false
  });
};

const close = () => {
  emit("update:dialogVisible", false);
};

/**
 * 单个图片文件上传时
 * 1.获取获取上传文件 url 构成图片回显
 * 2.uploadFiles 的size为1 时，uploadFiles的length==1时 无法触发change方法 此处设置为2， 并动态清除旧文件
 * 3.将只存有一个文件的uploadFiles 赋给tempImageFiles，等待提交时，被上传
 * @param uploadFile
 * @param uploadFiles
 * @param name
 */
const handleChange = (
  uploadFile: UploadFile,
  uploadFiles: UploadFiles,
  name: string
) => {
  // console.log(uploadFile,uploadFiles)
  let url = URL.createObjectURL(uploadFile.raw as UploadRawFile);
  singleImage[name] = url;
  if (uploadFiles.length > 1) {
    uploadFiles.splice(0, 1);
  }
  tempImageFiles[name] = uploadFiles;
};

defineExpose({
  uploadImages,
  selectUrl2SelectOptions,
});
</script>

<style scoped>
.customFrom {
  width: 100%;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
}

.image-upload >>> .el-upload.el-upload--picture-card {
  --el-upload-picture-card-size: 100px;
}

.single-image-upload >>> .el-upload.el-upload--picture-card {
  --el-upload-picture-card-size: 80px;
}

/* --el-upload-list-picture-card-size */
.image-upload >>> .el-upload-list--picture-card .el-upload-list__item {
  width: 100px;
  height: 100px;
}

.customFrom {
  --el-upload-picture-card-size: 80px;
  --el-upload-list-picture-card-size: 80px;
}

.single-image,
.single-image-icon {
  width: 80px;
  height: 80px;
}

.single-image-icon {
  font-size: 20px;
}
</style>
